package cn.com.cifi.mars.schedled;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import cn.com.cifi.mars.bean.bo.SysLogBO;
import cn.com.cifi.mars.bean.dto.SupplyPlanNewestVersionDto;
import cn.com.cifi.mars.bean.vo.sys.rsp.GroupUserVo;
import cn.com.cifi.mars.common.base.BaseAction;
import cn.com.cifi.mars.common.exception.MsgException;
import cn.com.cifi.mars.common.redis.RedisTemplateUtil;
import cn.com.cifi.mars.constant.Constants;
import cn.com.cifi.mars.constant.IsDeleteEnum;
import cn.com.cifi.mars.constant.IsSuccessEnum;
import cn.com.cifi.mars.constant.LogEventEnum;
import cn.com.cifi.mars.constant.LogSrcEnum;
import cn.com.cifi.mars.constant.LogTypeEnum;
import cn.com.cifi.mars.constant.OrgTypeEunm;
import cn.com.cifi.mars.constant.ProcessingModeEnum;
import cn.com.cifi.mars.constant.ProcessingStateEnum;
import cn.com.cifi.mars.constant.SalyTypeEnum;
import cn.com.cifi.mars.constant.StageStatusEnum;
import cn.com.cifi.mars.constant.SupplyConfirmStatusEnum;
import cn.com.cifi.mars.constant.VersionStatusEnum;
import cn.com.cifi.mars.constant.VersionTypeEunm;
import cn.com.cifi.mars.entity.MdmStage;
import cn.com.cifi.mars.entity.PriceVersion;
import cn.com.cifi.mars.entity.SupplyConfirmRecord;
import cn.com.cifi.mars.entity.SupplyConfirmRecordDetail;
import cn.com.cifi.mars.entity.SupplyPlanVersion;
import cn.com.cifi.mars.entity.SupplyPlanVersionDetail;
import cn.com.cifi.mars.entity.SysJob;
import cn.com.cifi.mars.mapper.mars.PriceVersionMapper;
import cn.com.cifi.mars.mapper.mars.SupplyConfirmRecordDetailMapper;
import cn.com.cifi.mars.mapper.mars.SupplyConfirmRecordMapper;
import cn.com.cifi.mars.mapper.mars.SupplyPlanVersionDetailMapper;
import cn.com.cifi.mars.mapper.mars.SupplyPlanVersionMapper;
import cn.com.cifi.mars.service.CommonService;
import cn.com.cifi.mars.service.DmDmSupplyCompareDetailService;
import cn.com.cifi.mars.service.DmOdsNosTradedataviewformarsService;
import cn.com.cifi.mars.service.IdmUserService;
import cn.com.cifi.mars.service.PriceVersionService;
import cn.com.cifi.mars.service.PriceVersionValueOrgService;
import cn.com.cifi.mars.service.SignPlanVersionService;
import cn.com.cifi.mars.service.StageService;
import cn.com.cifi.mars.service.SupplyPlanVersionService;
import cn.com.cifi.mars.service.SysJobService;
import cn.com.cifi.mars.service.SysLogService;
import cn.com.cifi.mars.service.impl.DmOdsMyVsMarsSContractServiceImpl;
import cn.com.cifi.mars.service.impl.MymRoomInfoServiceImpl;
import cn.com.cifi.mars.util.DateUtils;
import cn.com.cifi.mars.util.LocalDateTimeUtils;
import cn.com.cifi.mars.util.SynchrolockUtil;
import cn.com.cifi.mars.util.UUIDUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * 类名称：SupplyPlanTasks
 * 类描述：供货计划定时任务
 * 创建人：yyd
 * 创建时间：2019年11月30日 下午5:48:02
 * @author Administrator
 *
 */
@Slf4j
@Component
public class SupplyPlanTasks extends BaseAction {

	@Autowired
	private SysLogService sysLogService;
	
	@Autowired
	private IdmUserService idmUserService;
	
	@Autowired
	private SupplyPlanVersionService supplyPlanVersionService;

	@Autowired
	private PriceVersionService priceVersionService;
	
	@Autowired
	private SupplyConfirmRecordMapper supplyConfirmRecordMapper;
	
	@Autowired
	private SupplyPlanVersionMapper supplyPlanVersionMapper;
	
	@Autowired
	private SupplyConfirmRecordDetailMapper supplyConfirmRecordDetailMapper;
	
	@Autowired
	private SupplyPlanVersionDetailMapper supplyPlanVersionDetailMapper;
	
	@Autowired
	private SysJobService sysJobService;

	@Autowired
	private PriceVersionValueOrgService priceVersionValueOrgService;

	@Autowired
	private SignPlanVersionService signPlanVersionService;

	@Autowired
	private PriceVersionMapper priceVersionMapper;
	
	@Autowired
	private DmDmSupplyCompareDetailService dmDmSupplyCompareDetailService;

	@Autowired
	private DmOdsMyVsMarsSContractServiceImpl dmOdsMyVsMarsSContractServiceImpl;

	@Autowired
	private DmOdsNosTradedataviewformarsService dmOdsNosTradedataviewformarsService;

	@Autowired
	private SynchrolockUtil synchrolockUtil;
	
	@Autowired
	private RedisTemplateUtil redisTemplateUtil;

	@Autowired
	private MymRoomInfoServiceImpl mymRoomInfoServiceImpl;
	
	@Autowired
	private StageService stageService;

	@Autowired
	private CommonService commonService;

	/**
	 *
	 * 方法描述： 发送供货确认待办任务
	 * 创建人：yyd
	 * 创建时间：2019年12月4日 下午2:23:53
	 */
	@Scheduled(cron = "0 0 1 * * ?")
    public void supplyConfirmGTask() {
		log.info("#######################  供货确认定时发送待办任务  supplyConfirmGTask start  ##################### ");
		if(isLastTwoDayOfMonth()) {
			SysJob job = sysJobService.selectJobByCode(Constants.ZERO_NINE);
			LocalDateTime start = null;
			LocalDateTime end = null;
			if(null!=job) {
				Integer jobId = job.getId();
				int count = sysJobService.lockJobById(jobId);
				LocalDateTime lastUpdateTime = job.getUpdateTime();
				boolean flag = LocalDateTimeUtils.isValidTime(lastUpdateTime, Constants.THREE);
				if (count == 1 && !flag) {
					try {
						start = LocalDateTime.now();
						//发送待办任务
				    	sendSupplyConfirmTask();
						end =  LocalDateTime.now();
					}catch(Exception e) {
						log.error("#######   供货确认定时发送待办任务,MsgException:{}", e);
					} finally {
						sysJobService.resetJob(job,start,end);
		            }
				}else {
					sysJobService.resetStatus(job);
				}
			}
		}
		log.info("#######################  供货确认定时发送待办任务  supplyConfirmGTask end  ##################### ");
    }
	
	/**
	 * 
	 * @Description：判断是否月度前两天
	 * @return boolean
	 * @author：yyd
	 * @date：2020年4月29日 下午2:17:30
	 */
	private boolean isLastTwoDayOfMonth() {
		LocalDateTime time = LocalDateTime.now();
		LocalDateTime last = time.with(TemporalAdjusters.lastDayOfMonth()).minusDays(1);
		String curTimeStr = LocalDateTimeUtils.formatTime(LocalDateTime.now(),"yyyy-MM-dd");
		String lastTimeStr = LocalDateTimeUtils.formatTime(last,"yyyy-MM-dd");
		return curTimeStr.equals(lastTimeStr);
	}
	
	public void sendSupplyConfirmTask() {
		String curTimeStr = LocalDateTimeUtils.formatTime(LocalDateTime.now(),"yyyy-MM");
		//获取需要供货确认的版本
		List<SupplyPlanVersion> list = supplyPlanVersionService.queryNeedSupplyConfirmVersion(curTimeStr);
		List<String> projects = Collections.synchronizedList(new ArrayList<>());
		if(CollectionUtils.isNotEmpty(list)) {
			for(SupplyPlanVersion version : list) {
				String projectId = version.getProjectId();
				if(isNeedConfirm(projectId,curTimeStr)) {
					//发送门户待办信息
					try {
						supplyPlanVersionService.sendBackLog(projectId,version.getId(),1);
						projects.add(projectId);
					} catch (Exception e) {
						saveLog("定时任务","供货确认待办任务","待办消息发送失败："+projectId);
						log.error("#######   供货确认定时发送待办任务：", projectId+e);
					}
				}else {
					saveLog("定时任务","供货确认待办任务","不满足发送条件："+projectId);
				}
			}
		}
		
		saveLog("定时任务","供货确认待办任务","此次任务所包含项目："+projects.toString());
	}
	
	/**
	 * 
	 * 方法描述：检查逾期未确认供货计划
	 * 创建人：yyd
	 * 创建时间：2019年12月4日 下午2:23:53
	 */
	@Scheduled(cron = "0 0 6 1 * ?")
	public void checkOverdueUnconfirmed() {
		log.info("#######################  检查逾期未确认供货任务  checkOverdueUnconfirmed start  ##################### ");
		SysJob job = sysJobService.selectJobByCode(Constants.ZERO_TEN);
		LocalDateTime start = LocalDateTime.now();
		LocalDateTime end = null;
		if(null!=job) {
			Integer jobId = job.getId();
			int count = sysJobService.lockJobById(jobId);
			LocalDateTime lastUpdateTime = job.getUpdateTime();
			boolean flag = LocalDateTimeUtils.isValidTime(lastUpdateTime, Constants.THREE);
			if (count == 1 && !flag) {
				try {
					handleOverdueUnconfirmed();
					end =  LocalDateTime.now();
				}catch(Exception e) {
					log.error("#######   检查逾期未确认供货计划,MsgException:{}", e);
				} finally {
					sysJobService.resetJob(job,start,end);
	            }
			}else {
				sysJobService.resetStatus(job);
			}
		}
		log.info("#######################  检查逾期未确认供货任务  checkOverdueUnconfirmed end  ##################### ");
	}

	public void handleOverdueUnconfirmed() {
		String date = LocalDateTimeUtils.formatTime(LocalDateTimeUtils.getLastDayOfLastMonth(),"yyyy-MM");
		List<SupplyPlanVersion> list = supplyPlanVersionService.queryUnconfirmedVersions(date,VersionTypeEunm.DYNAMIC.getKey());
		List<String> projects = Collections.synchronizedList(new ArrayList<>());
		List<String> projectList = Collections.synchronizedList(new ArrayList<>());
		for(SupplyPlanVersion version : list) {
			String projectId = version.getProjectId();
			SupplyConfirmRecord supplyConfirmRecord = new SupplyConfirmRecord();
			String projectPrincipal = getProjectPMUser(projectId);
			if(!isNeedConfirm(projectId,date)) {
				supplyConfirmRecord.setConfirmStatus(SupplyConfirmStatusEnum.NONEED_CONFIRM.getKey());
			}else {
				supplyConfirmRecord.setConfirmStatus(SupplyConfirmStatusEnum.OVERDUE_UNCONFIRMED.getKey());
				projects.add(projectId);
			}
			supplyConfirmRecord.setId(UUIDUtils.create());
			supplyConfirmRecord.setProjectId(version.getProjectId());
			supplyConfirmRecord.setPrincipal(projectPrincipal);
			supplyConfirmRecord.setAffiliationMonth(date);
			supplyConfirmRecord.setIsDelete(IsDeleteEnum.NO.getKey());
			supplyConfirmRecord.setCreateBy(Constants.SYS);
			supplyConfirmRecord.setCreateTime(LocalDateTime.now());
			supplyConfirmRecordMapper.insert(supplyConfirmRecord);
			saveSupplyConfirmRecordDetail(version.getProjectId(),date,Constants.SYS);
			
			projectList.add(projectId);
		}
		//删除待办任务
		supplyPlanVersionService.deleteTodo(projectList);
		
		saveLog("定时任务","检查逾期未确认供货","此次任务所包含项目："+projects.toString());
	}
	/**
	 * 
	 * @Description：检查项目是否需要确认供货
	 * @author：yyd
	 * @date：2020年3月6日 下午5:20:59
	 */
	public boolean isNeedConfirm(String projectId,String affiliationMonth) {
		boolean flag = false;
		List<MdmStage> stageList = stageService.selectByProjectId(projectId, IsDeleteEnum.NO.getKey());
		List<String> stageStatus = stageList.stream().map(s-> s.getStatus()).collect(Collectors.toList());
		if(stageStatus.contains(StageStatusEnum.CTIVE.getKey())) {
			List<SupplyPlanVersion> list = supplyPlanVersionMapper.selectNewestDynamicVersion(projectId,affiliationMonth,IsDeleteEnum.NO.getKey());
			for(SupplyPlanVersion version : list) {
				List<SupplyPlanVersionDetail> detailList = supplyPlanVersionDetailMapper.selectByVersionId(version.getId(), IsDeleteEnum.NO.getKey());
				for(SupplyPlanVersionDetail detail : detailList) {
					if(detail.getType().equals(OrgTypeEunm.ORG_BUILD.getKey())) {
						LocalDateTime supplyDateActual = detail.getSupplyDateActual() == null ? detail.getSupplyTimeVirtual() : detail.getSupplyDateActual();
						String bussinessType = detail.getBusinessType();
						if(bussinessType.equals(SalyTypeEnum.SALABLE.getKey()) || bussinessType.equals(SalyTypeEnum.STAGE_SELF_SUSTAINMENT.getKey()) ) {
							if(supplyDateActual == null) {
								flag = true;
								return flag;
							}
						}
					}
				}
			}
		}
		return flag;
	}
	
	private void saveSupplyConfirmRecordDetail(String projectId,String versionDate,String alias) {
		List<SupplyConfirmRecordDetail> detailList =Collections.synchronizedList(new ArrayList<>());
		//根据项目获取各分期下最新供货计划动态版本信息
		List<SupplyPlanNewestVersionDto> list = supplyConfirmRecordDetailMapper.selectNewestVersionDetail(projectId,versionDate,IsDeleteEnum.NO.getKey());
		List<String> versionIds = Collections.synchronizedList(new ArrayList<>());
		if(CollectionUtils.isNotEmpty(list)) {
			for(SupplyPlanNewestVersionDto dto : list) {
				SupplyConfirmRecordDetail detail = new SupplyConfirmRecordDetail();
				detail.setId(UUIDUtils.create());
				detail.setProjectId(projectId);
				detail.setStageId(dto.getProjectFId());
				detail.setVersionId(dto.getVersionId());
				detail.setVersionNum(dto.getVersionNum());
				detail.setAffiliationMonth(versionDate);
				detail.setCreateBy(alias);
				detail.setCreateTime(LocalDateTime.now());
				detail.setIsDelete(IsDeleteEnum.NO.getKey());
				detailList.add(detail);
				versionIds.add(dto.getVersionId());
			}
			supplyConfirmRecordDetailMapper.batchInsert(detailList);
		}
	}
	
	/**
	 * 
	 * @Description：获取项目PM用户
	 * @param projectId 项目ID
	 * @return String
	 * @author：yyd
	 * @date：2020年2月6日 上午10:30:22
	 */
	private String getProjectPMUser(String projectId) {
		StringBuilder sb = new StringBuilder();
		String squ = "";
		HashSet<GroupUserVo> set = idmUserService.getGroupUserInfo(Constants.PROJECT_OPERATION_PM,projectId);
		for(GroupUserVo vo : set) {
			sb.append(squ).append(vo.getUsercn());
			squ ="、";
		}
		return sb.toString();
	}

	/**
	 * 
	 * 方法描述： 货值定稿定时任务
	 * 创建人：yyd
	 * 创建时间：2019年12月4日 下午2:23:53
	 */
	@Scheduled(cron = "0 0 6 * * ?")
	public void finalizationTask() {
		log.info("#######################  定稿任务 finalizationTask start  ##################### ");
		SysJob job = sysJobService.selectJobByCode(Constants.ZERO_ELEVEN);
		LocalDateTime start = null;
		LocalDateTime end = null;
		if(null!=job) {
			Integer jobId = job.getId();
			int count = sysJobService.lockJobById(jobId);
			LocalDateTime lastUpdateTime = job.getUpdateTime();
			boolean flag = LocalDateTimeUtils.isValidTime(lastUpdateTime, Constants.THREE);
			if (count == 1 && !flag) {
				try {
					LocalDateTime now = LocalDateTime.now();
					LocalDate ascriptionDate = LocalDate.now();
					int day = now.getDayOfMonth();
					int hour = now.getHour();
					if (day == Constants.ONE && hour == Constants.SIX){
						ascriptionDate = ascriptionDate.minusMonths(1);
					}else{
						return;
					}
					//TODO 明源签约数据改成ESB下发，上线需修改
					//增量拉取明源签约数据接口
					try{
						dmOdsMyVsMarsSContractServiceImpl.syncIncrement();
					}catch (Exception e){
						log.error("#########  增量拉取明源签约数据接口  错误信息："+e.getMessage(), e);
					}

					//增量拉取NOS数据接口
					try {
						dmOdsNosTradedataviewformarsService.syncNosContact();
					}catch (Exception e){
						log.error("#########  NOS 全量拉取签约数据接口 错误信息："+e.getMessage(), e);
					}

					List<String> priceIds = new ArrayList<>();

					//添加同步锁
					boolean isLocked = synchrolockUtil.islocked(Constants.RedisSyncKey);

					try {
						finalizeTaskInfo(now, ascriptionDate, priceIds, null);
					}catch (Exception e){
						log.error("#########  finalizeTaskInfo  错误信息："+e.getMessage(), e);
					}finally {
						synchrolockUtil.unlock(Constants.RedisSyncKey);
					}

				}catch(Exception e) {
					log.error("#######  定稿错误：e"+e);
					saveLog("定时定稿","定稿失败信息", e.toString());
				} finally {
					//5、重置定时任务状态
					sysJobService.resetJob(job,start,end);
				}
			}else {
				sysJobService.resetStatus(job);
			}
		}
		log.info("#######################  定稿任务 finalizationTask end  ##################### ");
	}
	
	public void finalizeTaskInfo(LocalDateTime now, LocalDate ascriptionDate, List<String> priceIds, String projectFid) {
		//有动态版或一房一价后每月1日6点定稿封板
		List<PriceVersion> priceVersionList = priceVersionMapper.selectAllSaleAndDynamicVersion(projectFid);
		Set<String> stageIds = Optional.of(priceVersionList).orElseGet(ArrayList::new)
				.stream().map(PriceVersion::getProjectfId)
				.collect(Collectors.toSet());
		//全盘最新需要货值定稿版本
		List<PriceVersion> finalizePriceVersionList = new ArrayList<PriceVersion>();
		//分期最新货值定稿版本集合
		Map<String, PriceVersion> finalizePriceVersionMap = new HashMap<String, PriceVersion>();
		if (CollectionUtils.isNotEmpty(stageIds)){
			for (String stageId : stageIds){
				PriceVersion newestPriceVersion = priceVersionService.getNewestPriceVersion(stageId);
				if (newestPriceVersion != null){
					finalizePriceVersionList.add(newestPriceVersion);
					finalizePriceVersionMap.put(stageId, newestPriceVersion);
				}
			}
		}
		
		saveLog("货值定稿","货值定稿分期",ascriptionDate+"满足定稿封版条件的分期:"+finalizePriceVersionMap.toString());

		if (CollectionUtils.isNotEmpty(finalizePriceVersionList)){
			 for (PriceVersion priceVersion : finalizePriceVersionList){
				try{
					finalizationInfo(now, ascriptionDate, priceIds, priceVersion);
				}catch (MsgException e){
					saveLog("货值定时定稿生成定稿版本","货值定时定稿生成定稿版本失败信息", e.getMsg()+":"+priceVersion);
					log.error("#######  货值 {}, 货值定时定稿生成定稿版本：MsgException:{}", priceVersion.toString(), e.getMsg());
				}catch (Exception e){
					saveLog("货值定时定稿生成定稿版本","货值定时定稿生成定稿版本失败信息", e.toString());
					log.error("#######  货值 {}, 货值定时定稿生成定稿版本：exception:{}", priceVersion.toString(), e);
				}
			}
		}

		LocalDateTime afterNow = LocalDateTime.now();
		LocalDate afterAscriptionDate = ascriptionDate.minusMonths(-1);
		//查询被定稿版本（月度动态）归属月份，是否存在（待编制、编制中、待提交审批、审批中、驳回、撤回）等在途的货值版本
		List<PriceVersion> notFinishPriceVersionList = priceVersionMapper.selectNewestVersionGroupByStageId(Arrays.asList(VersionTypeEunm.DYNAMIC.getKey()), Arrays.asList(VersionStatusEnum.NOTPREPARED.getKey(),
				VersionStatusEnum.ORGANIZATION.getKey(), VersionStatusEnum.EXAMINEDAPPROVED.getKey(), VersionStatusEnum.APPROVED.getKey(), VersionStatusEnum.FAILUREAPPROVED.getKey()), projectFid, IsDeleteEnum.NO.getKey());
		if (CollectionUtils.isNotEmpty(notFinishPriceVersionList)){
			for(PriceVersion notFinishVersion: notFinishPriceVersionList){
				//定稿版本去除跨月版本
				finalizePriceVersionMap.remove(notFinishVersion.getProjectfId());
				try{
					priceVersionService.updateAfterAscriptionVersion(notFinishVersion, afterNow, afterAscriptionDate);
				}catch (MsgException e){
					log.error("#######  货值 {}, 货值定时定稿跨越版本挪动：MsgException:{}", notFinishVersion.toString(), e.getMsg());
				}catch (Exception e){
					log.error("#######  货值 {}, 货值定时定稿跨越版本挪动：exception:{}", notFinishVersion.toString(), e);
				}

				//货值版本在途（待编制/编制中/待提交审批/审批被驳回）刷新
				if(notFinishVersion.getVersionState().equals(VersionStatusEnum.NOTPREPARED.getKey())
						|| notFinishVersion.getVersionState().equals(VersionStatusEnum.ORGANIZATION.getKey())
						|| notFinishVersion.getVersionState().equals(VersionStatusEnum.EXAMINEDAPPROVED.getKey())
						|| notFinishVersion.getVersionState().equals(VersionStatusEnum.FAILUREAPPROVED.getKey()) ){
					try{
						priceVersionValueOrgService.priceRefreshActualValueInfo(notFinishVersion.getProjectfId(), notFinishVersion, null, null, LocalDateTime.now(), null , null);
					}catch (Exception e){
						log.error("#######  货值 {}, 货值定时定稿跨越版本挪动-刷新：exception:{}", notFinishVersion.toString(), e);
					}
				}else if (notFinishVersion.getVersionState().equals(VersionStatusEnum.APPROVED.getKey())){
					try{
						//定稿审批中添加一条延后处理的系统任务
						mymRoomInfoServiceImpl.noticeDownsRecordProcessedInfo(notFinishVersion.getCountingSystemCode().equals(Constants.MY)?Constants.NOTICE_MY_DELAY:Constants.NOTICE_NOS_DELAY, null, notFinishVersion.getId(), notFinishVersion.getProjectId(), notFinishVersion.getProjectfId(), ProcessingStateEnum.UNTREATED.getKey(), ProcessingModeEnum.SYSTEM_DELAY.getKey(), Constants.DG, now);
					}catch (Exception e){
						log.error("#######  货值 {}, 货值定时定稿跨越版本挪动-添加延后处理系统任务：exception:{}", notFinishVersion.toString(), e);
					}
				}
			}
		}

		//生成次月版本条件，查询被定稿版本生成下月版本(除去再途跨月版本)
		if (finalizePriceVersionMap != null && !finalizePriceVersionMap.isEmpty()){
			for (Map.Entry<String, PriceVersion> saleProjectVersionMap: finalizePriceVersionMap.entrySet()){
				PriceVersion saleProjectVersion = saleProjectVersionMap.getValue();
				String versionId = "";
				try{
					 versionId = priceVersionValueOrgService.createSysAppointDynamicVersion(saleProjectVersion.getProjectfId(), saleProjectVersion, 0, afterAscriptionDate, "定稿生成月初版本", 6,null, Constants.DG);
				}catch (MsgException e){
					log.error("#######  货值 {}, 货值定稿创建月初版本：MsgException:{}", e.getMsg());
					saveLog("货值定稿创建月初版本","货值定稿创建月初版本失败信息", "分期ID:"+saleProjectVersion.getProjectfId());
				}catch (Exception e){
					log.error("#######  货值 {}, 货值定稿创建月初版本：exception:{}", saleProjectVersion.toString(), e);
					saveLog("货值定稿创建月初版本","货值定稿创建月初版本失败信息", "分期ID:"+saleProjectVersion.getProjectfId());
				}
				if(!versionId.equals("")) {
					supplyPlanVersionService.createSupplyPlanVersion(versionId, VersionTypeEunm.DYNAMIC.getKey(), Constants.SYS);
				}else {
					saveLog("货值定稿创建月初供货版本","货值定稿创建月初供货版本", "分期ID:"+saleProjectVersion.getProjectfId());
				}
			}
		}
	}

	public void finalizationInfo(LocalDateTime now, LocalDate ascriptionDate, List<String> priceIds, PriceVersion priceVersion) {
		String versionState = priceVersion.getVersionState();
		if (StringUtils.isNotEmpty(versionState) && versionState.equals(VersionStatusEnum.SUCCESSAPPROVED.getKey())){
			//创建货值定稿版本
			String versionId = priceVersionValueOrgService.createSysAppointDynamicVersion(priceVersion.getProjectfId(), priceVersion, 1, ascriptionDate, "定稿生成", 4,null, Constants.DG);
			//创建供货定稿版本
			supplyPlanVersionService.finalizeCreateSupplyPlanVersion(versionId, VersionTypeEunm.DYNAMIC.getKey(), Constants.SYS);
			priceIds.add(versionId);
			recordLog("货值管理", "定稿复制生城货值版本", versionId);
		}else if (StringUtils.isNotEmpty(versionState) && versionState.equals(VersionStatusEnum.SYSGENERATION.getKey())){
			//查看货值版本是否有被供货确认使用
			boolean isComfirm = supplyPlanVersionService.supplyIsComfirm(priceVersion.getId());
			if (isComfirm){
				//创建货值定稿版本
				String versionId = priceVersionValueOrgService.createSysAppointDynamicVersion(priceVersion.getProjectfId(), priceVersion, 1, ascriptionDate, "定稿生成",4,null, Constants.DG);
				//创建供货定稿版本
				supplyPlanVersionService.finalizeCreateSupplyPlanVersion(versionId, VersionTypeEunm.DYNAMIC.getKey(), Constants.SYS);
				priceIds.add(versionId);
				recordLog("货值管理", "定稿复制生城货值版本", versionId);
			}else{
				//查看货值版本是否有被签约使用
				List<String> itemVersionIds = Arrays.asList(priceVersion.getId());
				Map<String, Boolean> signMap = signPlanVersionService.priceBoolean(itemVersionIds);
				Boolean isSign = signMap.get(priceVersion.getId());
				if (isSign){
					//创建货值定稿版本
					String versionId = priceVersionValueOrgService.createSysAppointDynamicVersion(priceVersion.getProjectfId(), priceVersion, 1, ascriptionDate, "定稿生成", 4,null, Constants.DG);
					//创建供货定稿版本
					supplyPlanVersionService.finalizeCreateSupplyPlanVersion(versionId, VersionTypeEunm.DYNAMIC.getKey(), Constants.SYS);
					priceIds.add(versionId);
					recordLog("货值管理", "定稿复制生城货值版本", versionId);
				}else{
					//查看货值版本是否是定稿版
					Integer isFinalization = priceVersion.getIsFinalization();
					if (isFinalization != null && isFinalization.equals(IsDeleteEnum.YES.getKey())){
						//创建货值定稿版本
						String versionId = priceVersionValueOrgService.createSysAppointDynamicVersion(priceVersion.getProjectfId(), priceVersion, 1, ascriptionDate, "定稿生成",  4,null, Constants.DG);
						//创建供货定稿版本
						supplyPlanVersionService.finalizeCreateSupplyPlanVersion(versionId, VersionTypeEunm.DYNAMIC.getKey(), Constants.SYS);
						priceIds.add(versionId);
						recordLog("货值管理", "定稿复制生城货值版本", versionId);
					}else{
						//刷新货值定稿版本
						priceVersionValueOrgService.priceRefreshActualValueInfo(priceVersion.getProjectfId(), priceVersion, 1, ascriptionDate, LocalDateTime.now(), null, null);
						//创建供货定稿版本
						supplyPlanVersionService.finalizeCreateSupplyPlanVersion(priceVersion.getId(), priceVersion.getVersionType(), Constants.SYS);
						priceIds.add(priceVersion.getId());
						recordLog("货值管理", "定稿刷新货值版本", priceVersion.getId());
					}
				}
			}
		}
	}

	/**
	  * 刷新供货对比表
    * 每天0点开始，每6小时执行一次
    */
	@Scheduled(cron = "0 0 0/6 * * ? ")
	public void initSupplyCompareReportTask() {
		boolean appointIP = commonService.isAppointIP();
		if (!appointIP){
			return;
		}
		log.info("#######################  定时初始化版本对比数据任务  initSupplyCompareReportTask start  ##################### ");
		SysJob job = sysJobService.selectJobByCode(Constants.ZERO_SEVENTEEN);
		LocalDateTime start = null;
		LocalDateTime end = null;
		if(null!=job) {
			Integer jobId = job.getId();
			int count = sysJobService.lockJobById(jobId);
			LocalDateTime lastUpdateTime = job.getUpdateTime();
			boolean flag = LocalDateTimeUtils.isValidTime(lastUpdateTime, Constants.THREE);
			if (count == 1 && !flag) {
				try {
					start = LocalDateTime.now();
					String strDate = LocalDateTimeUtils.formatTime(LocalDateTime.now(),DateUtils.DATE_JFP_STR);
			    	//初始化版本对比数据
					dmDmSupplyCompareDetailService.initSupplyCompareData(strDate);
					end =  LocalDateTime.now();
				}catch(Exception e) {
					log.error("#######  定时初始化版本对比：MsgException:{}",e);
				} finally {
					//5、重置定时任务状态
					sysJobService.resetJob(job,start,end);
	            }
			}else {
				sysJobService.resetStatus(job);
			}
		}
		log.info("#######################  定时初始化版本对比数据任务  initSupplyCompareReportTask end  ##################### ");
	}
	
	/**
	 * 
	 * @Description： 缓存确认供货时间
	 * @author：yyd
	 * @date：2020年4月6日 下午4:18:50
	 */
	@Scheduled(cron = "0 0 0 * * ?")
	public void cacheConfirmSupplyTimeTask() {
		log.info("#######################   缓存确认供货时间任务  cacheConfirmSupplyTimeTask start  ##################### ");
		if(redisTemplateUtil.get(Constants.RedisConfirmDate) != null) {
			redisTemplateUtil.delete(Constants.RedisConfirmDate);
		}
		if(redisTemplateUtil.get(Constants.RedisConfirmShowDate) != null) {
			redisTemplateUtil.delete(Constants.RedisConfirmShowDate);
		}
		
		DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime now = LocalDateTime.now();
		String strDate = LocalDateTimeUtils.formatTime(LocalDateTime.now(),DateUtils.DATE_JFP_STR);
		String showMonth = "";
		String affiliationMonth = supplyPlanVersionService.getAffiliationMonth(strDate);
		String comfirmTime = supplyPlanVersionService.getComfirmTime();
		LocalDateTime endComfirmTime = LocalDateTimeUtils.strToDate(comfirmTime, df);
		LocalDateTime beginTimeTemp = endComfirmTime.minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
		LocalDateTime beginComfirmTime = beginTimeTemp.with(TemporalAdjusters.lastDayOfMonth()).minusDays(1);
		if(now.isBefore(beginComfirmTime)) {
			showMonth = LocalDateTimeUtils.getLastMonth(strDate);
		}else {
			showMonth = affiliationMonth;
		}
		redisTemplateUtil.set(Constants.RedisConfirmDate, affiliationMonth,60 * 48L);
		redisTemplateUtil.set(Constants.RedisConfirmShowDate, showMonth, 60 * 48L);
		log.info("#######################   缓存确认供货时间任务  cacheConfirmSupplyTimeTask start  ##################### ");
	}
	
	private boolean recordLog(String module,String title,String content) {
        SysLogBO bo = new SysLogBO();
        bo.setEvent(LogEventEnum.ADD);
        bo.setSource(LogSrcEnum.PC);
        bo.setModule(module);
        bo.setTitle(title);
        bo.setContent(content);
        bo.setType(LogTypeEnum.ZERO.getKey());
        bo.setIsSuccess(IsSuccessEnum.SUCCESS.getKey());
        return sysLogService.add(bo,Constants.SYS);
    }
	
	/**
	 * 
	 * @Description：保存日志
	 * @author：yyd
	 * @date：2020年2月6日 上午10:30:57
	 */
	private boolean saveLog(String module,String title,String content) {
		SysLogBO bo = new SysLogBO();
		bo.setEvent(LogEventEnum.BROWSE);
    	bo.setSource(LogSrcEnum.PC);
    	bo.setModule(module);
    	bo.setTitle(title);
    	bo.setContent(content);
    	bo.setType(LogTypeEnum.ZERO.getKey());
    	bo.setIsSuccess(IsSuccessEnum.SUCCESS.getKey());
        return sysLogService.add(bo,Constants.SYS);
	}

}